import * as THREE from "three";
import {
  EdgesGeometry,
  Group,
  LineBasicMaterial,
  LineSegments,
  Mesh,
} from "three";
import {
  Line2,
  LineGeometry,
  LineMaterial,
  OrbitControls,
} from "three/examples/jsm/Addons.js";

const meshEdgeMaterialsCache = {};
const lineMaterialsCache = {};

export class E3Utils {
  static createLine2(positions, material = E3Utils.getLine2Material()) {
    const geometry = new LineGeometry();
    geometry.setPositions(positions);
    return new Line2(geometry, material);
  }

  static getLine2Material(color = 0xff0000, linewidth = 2, key = null) {
    if (!key) {
      key = `${color}-${linewidth}`;
    }
    let lineMaterial = lineMaterialsCache[key];
    if (!lineMaterial) {
      lineMaterial = new LineMaterial({ color, linewidth });
      lineMaterialsCache[key] = lineMaterial;
    }
    return lineMaterial;
  }

  static meshAddEdge(mesh) {
    const lineGeometry = new EdgesGeometry(mesh.geometry);
    let edgeMaterial = E3Utils.getEdgeMaterial(mesh.material);
    const line = new LineSegments(lineGeometry, edgeMaterial);
    mesh.add(line);
    return mesh;
  }

  static getEdgeMaterial(material) {
    const geometryColor = material.color.getHex();
    let edgeMaterial = meshEdgeMaterialsCache[geometryColor];
    if (!edgeMaterial) {
      edgeMaterial = new LineBasicMaterial({
        color: geometryColor,
        opacity: 0.1,
        transparent: true,
      });
      meshEdgeMaterialsCache[geometryColor] = edgeMaterial;
    }
    return edgeMaterial;
  }
}

// 1. 设置场景
const scene = new THREE.Scene();

// 2. 设置相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 15;

const ambientLight = new THREE.AmbientLight(0xffffff, 0.8);
scene.add(ambientLight);

// 3. 设置渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const materialS = {};
const concreteColor = new THREE.Color(0xa5a5a5);
let cube;
{
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshPhysicalMaterial({
    color: concreteColor,
    metalness: 0.1,
    roughness: 0.7,
  });
  cube = new THREE.Mesh(geometry, material);
  window.cube = cube;
  scene.add(cube);

  E3Utils.meshAddEdge(cube);
}
// 4. 创建线条几何体
const geometry = new LineGeometry();
geometry.setPositions([-10, 0, 0, 0, 10, 0, 10, 0, 0]);

// 5. 创建线条材质
const material = E3Utils.getLine2Material(0xff0000, 5);
window.material = material;

// 6. 创建线条对象
const line = new Line2(geometry, material);

// 7. 将线条添加到场景中
scene.add(line);

const controls = new OrbitControls(camera, renderer.domElement);

{
  const geometry = new THREE.BoxGeometry(5, 5, 5);
  const lineGeometry = new THREE.EdgesGeometry(geometry);
  const material = new THREE.LineBasicMaterial({ color: 0x0000ff });
  const line = new THREE.LineSegments(lineGeometry, material);
  scene.add(line);
}

// 8. 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

window.scene = scene;
